dumpsys meminfo 的原理和应用
A部分
A.1 smaps
Pss
PSS (Proportional Set Size) = 进程独占的内存 + 进程程共享的内存 / 映射次数。
内存的管理是以 page 为单位的, 如果 page 的 _refcount或者 _mapcount为 1, 那么就是进程独占的内存. 也叫 private. 如果 page 的 _mapcount 为 n ( n >= 2), 这块内存以 page / n 来统计。Private_Dirty
Private 在上面已经说过了。 而 Dirty 分为 PageDirty和 pte_dirty. PageDirty就是所说的脏页( 文件读到内存中被修改过, 就会标记为脏页)。 pte_dirty则当 vma 用于 anonymous 的时候, 读写这段 vma 时候, 触发 page fault, 调用 do_anonymous_page , 如果vma_flags中包含 VM_WRITE, 则会通过 pte_mkdirty(entry)标记。Private_Clean
与 Private_Dirty 相反。Swap
一般情况下, 在 Android 中就是 zram, 通过压缩内存页面并将其放入动态分配的内存交换区来增加系统中的可用内存量, 压缩的都是匿名页。
当vma->vm_file不为空的时候,名字为file->f_path文件路径,文件包含存储介质的文件,也包含设备文件,虚拟文件等(everything is a file)。
类型 |
匹配字符串 |
Ashmem |
/dev/ashmem |
Gfx dev |
/dev/kgsl-3d0 |
Other dev |
/dev/* |
.so mmap |
*.so 例 /system/lib64/libstdc++.so |
.jar mmap |
*.jar 例 /system/framework/framework.jar |
.apk mmap |
*.apk 例 /system/framework/framework-res.apk |
.ttf mmap |
*.ttf 例 /system/fonts/Roboto-BlackItalic.ttf |
.dex mmap |
*.vdex 例 /system/framework/boot.vdex |
.oat mmap |
*.oat 例 /system/framework/arm64/boot-ext.oat |
.art mmap |
*.art 例 /system/framework/arm64/boot.art |
Other mmap |
不属于上面的类型 |
这种用途的vma的名字[anon:开头,虽然叫匿名,但显示哪里分配的,比如说上图的[anon:libc_malloc],就说明这段vma是从libc_malloc中分配出去的。
老的内核版本是没有这个域的,后来因为userspace的进程有很多种不同的分配器(allocators) , 如果出现异常不知道哪里出了问题,就比如说如何区分Dalvik Heap 和Native Heap, 后来android提了一笔可以修改内存区域的名字的补丁,通过prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, start, len, (unsigned long)name)系统调用,就可以把名字保存在vma_area_struct ->shared.anon_name有趣的这是个userspace指针,来降低mm子系统的复杂性.同时复用了vma_area_struct结构体的shared(利用union),shared用在file-backed mappings,这样就不和用于匿名的vma冲突.连内存都省了(这可能就是程序的魅力所在)。
类型 |
匹配字符串 |
Native Heap |
[anon:libc_malloc] 或 [heap] |
Dalvik Heap |
[anon:dalvik-* |
Dalvik Other |
Dalvik Heap 的部分 比如 [anon:dalvik-indirect ref 开头的) |
A.2进程中读取
mallinfo()
返回内存分配的统计信息, 函数声明在 android/bionic/libc/include/malloc.h,函数定义在 android/bionic/libc/bionic/malloc_common.h.
#if defined(USE_SCUDO) #include "scudo.h" #else #include "jemalloc.h" #endif |
Native Heap Size |
mallinfo.usmblks |
Maximum total allocated space |
Native Heap Alloc |
mallinfo.uordblks |
Total allocated space |
Native Heap Free |
mallinfo.fordblks |
Total free space |
runtime
Runtime runtime = Runtime.getRuntime(); //
Do GC since countInstancesOfClass counts unreachable
objects. long dalvikMax
= runtime.totalMemory() / 1024; |
Dalvik Heap Free |
runtime.freeMemory() |
Dalvik Heap Size |
runtime.totalMemory() |
Dalvik Heap Alloc |
Dalvik Heap Size - Dalvik Heap Free |
A.3 memtrack.vendor_xxx.so
B部分
Java Heap
//
dalvik private_dirty |
Native Heap
nativePrivateDirty; // libc_malloc |
Code
//
so mmap private_dirty + private_clean |
Stack
//
stack private_dirty |
Graphic
//Gfx
Dev private_dirty + private_clean
|
System
应用
B版本